<?php
namespace app\common\model\shop\self;

use think\admin\Model;
use think\admin\model\SystemUser;

class SelfGoodsModel extends Model
{
    // 设置当前模型对应的完整数据表名称
    protected $name = 'shop_goods_self';

    // 自动写入时间戳
    protected $autoWriteTimestamp = false;

    /**
     * 日志名称
     * @var string
     */
    protected $oplogName = '自有平台商品';

    /**
     * 日志类型
     * @var string
     */
    protected $oplogType = '自有平台商品管理';

    /**
     * 获取来源集合
     * @Description
     * @author wangqinghui
     * @date 2025-01-10 16:14
     * @return array
     */
    public static function from_arr() : array
    {
        return [0 => lang('未知'), 1 => lang('数据采集'), 2 => lang('手工创建')];
    }

    /**
     * 推送状态
     * @Description
     * @author wangqinghui
     * @date 2025-01-10 16:14
     * @return array
     */
    public static function pushStatusArr() : array
    {
        return [0 => lang('未推送'), 1 => lang('推送处理中'), 2 => lang('推送成功'), 3 => lang('推送失败')];
    }

    /**
     * 商品推荐集合
     * @Description
     * @author wangqinghui
     * @date 2025-01-11 15:43
     * @return array
     */
    public static function getRecommendArr() : array
    {
        return ['is_hot' => lang('热卖单品'), 'is_benefit' => lang('促销单品'), 'is_best' => lang('精品推荐'), 'is_new' => lang('首发新品'), 'is_good' => lang('优品推荐')];
    }

    public function userName(): \think\model\relation\HasOne
    {
        return $this->hasOne(SystemUser::class,'id','user_id')->bind(['create_name' => 'nickname']);
    }

    public function updateName(): \think\model\relation\HasOne
    {
        return $this->hasOne(SystemUser::class,'id','update_user_id')->bind(['update_name' => 'nickname']);
    }

    public function skuList(): \think\model\relation\HasMany
    {
        return $this->hasMany(SelfGoodsSkuModel::class, 'goods_id');
    }

    /**
     * 生成spu编码
     * @Description
     * @author wangqinghui
     * @date 2025-01-10 14:59
     * @return string
     */
    public function createSPU(): string
    {
        // 获取
        $day_time = date('Y-m-d') . ' 00:00:00';
        $count = self::mk()->where('create_at', '>', $day_time)->count();
        $spu_code = date('Ymd') . str_pad($count + 1, 6, '0', STR_PAD_LEFT);
        return (string)$spu_code;
    }

    /**
     * 获取需要推送的商品数据
     * @param array $goods_list
     * @param array $ids
     * @param array $shop_data
     * @Description
     * @author wangqinghui
     * @date 2025-01-15 14:49
     * @return array
     */
    public function getPushGoodsData(array $goods_list,array $ids, array $shop_data = []) : array
    {
        $err_data = $success_data = [];
        if(empty($goods_list)){
            $err_data[] = '没有需要推送的商品数据';
            return ['success' => [], 'error' => $err_data];
        }
        $field = 'id,goods_id,image as pic,price,sale_price as ot_price,goods_nu as bar_code,weight,volume,cost,attribute_ids,attribute_titles';
        $sku_list = SelfGoodsSkuModel::mk()->field($field)->whereIn('goods_id', $ids)->select()->toArray();
        if(empty($sku_list)){
            $err_data[] = '没有需要推送的商品数据';
            return ['success' => [], 'error' => $err_data];
        }
        // 获取sku规格
        $sku_attr_ids = array_filter(array_column($sku_list, 'attribute_ids'));
        $sku_arr_data = [];
        if(!empty($sku_attr_ids)){
            $sku_attr_ids_str = implode(',', $sku_attr_ids);
            $sku_arr_data = SelfGoodsAttributeModel::mk()->whereIn('id', $sku_attr_ids_str)->column('id,key_name,value_name', 'id');
        }
        // 获取商品图片
        $goods_image_list = SelfGoodsImageModel::mk()->whereIn('goods_id', $ids)->select()->toArray();
        $goods_image_data = [];
        if(!empty($goods_image_list)){
            foreach($goods_image_list as $key => $image_info){
                $goods_image_data[$image_info['goods_id']][] = $image_info['image'];
            }
        }
        $sku_data = $goods_attr_data = [];
        foreach($sku_list as $key => $sku_info){
            $goods_id = $sku_info['goods_id'];
            $sku_info['detail'] = [];
            $sku_attr_detail_data = [];
            if(!empty($sku_info['attribute_ids'])){
                $attr_id_arr = explode(',', $sku_info['attribute_ids']);
                foreach($attr_id_arr as $attr_key => $attr_val){
                    $attr_key_name = !empty($sku_arr_data[$attr_val]['key_name']) ? $sku_arr_data[$attr_val]['key_name'] : '';
                    $attr_value_name = !empty($sku_arr_data[$attr_val]['value_name']) ? $sku_arr_data[$attr_val]['value_name'] : '';
                    $sku_info['detail'][$attr_key_name] = $attr_value_name;
                    $sku_attr_detail_data[$attr_key_name][] = $attr_value_name;
                    $sku_info['value'.($attr_key+1)] = $attr_value_name;
                    $goods_attr_data[$goods_id][$attr_key_name]['value'] = $attr_key_name;
                    $goods_attr_data[$goods_id][$attr_key_name]['detail'][] = $attr_value_name;
                }
            }
            unset($sku_info['id'], $sku_info['attribute_ids'], $sku_info['attribute_titles'], $sku_info['goods_id']);
            $sku_info['weight'] = bcdiv($sku_info['weight'],1000, 2);//重量（KG）
            $sku_info['volume'] = bcdiv($sku_info['volume'],1000000, 2);//体积(m³)
            $sku_data[$goods_id][] = $sku_info;
        }
        
        // 组装推送数据
        foreach ($goods_list as $key => $goods_info) {
            $goods_id = $goods_info['id'];// 商品ID
            $shop_id = $goods_info['shop_id'] ?? 0;
            if(empty($shop_id)){
                $err_data[] = 'SPU:'.$goods_info['spu_code'].'无店铺信息';
                continue;
            }
            $shop_info = $shop_data[$shop_id] ?? [];
            if(empty($shop_info)){
                $err_data[] = 'SPU:'.$goods_info['spu_code'].'店铺信息有误';
                continue;
            }
            $assem_goods = [
                'act_gid' => $goods_id,// 商品ID
                'cate_id' => !empty($goods_info['category_id']) ? json_decode($goods_info['category_id'], 1) : [],// 分类
                'store_info'    =>  $goods_info['short_desc'] ?? '',// 商品简介
                'keyword'   =>  $goods_info['keyword'] ?? '',// 商品关键字
                'unit_name' =>  $goods_info['unit_name'] ?? '',//商品单位名称
                'store_name' =>  $goods_info['title'] ?? '',// 商品名称
                'postage' =>  $goods_info['postage'] ?? 0,//邮费 0元则包邮
                'slider_image' =>  !empty($goods_image_data[$goods_id]) ? $goods_image_data[$goods_id] : [],//轮播图
                'description' =>  $goods_info['long_desc'] ?? '',//商品详情
                'spec_type' => $goods_info['mode_type'] ?? 0,//规格类型 0单规格 1多规格
                'is_limit' => $goods_info['is_limit'] ?? 0,//是否开启限购 1开启 0关闭 默认为0
                'vip_product'   =>  $goods_info['vip_product'] ?? 0,//是否开启会员价格 1开启 0关闭
                'is_show'   =>  $goods_info['is_show'] ?? 0,//上架状态 1上架 0下架
                'presale'   =>  $goods_info['presale'] ?? 0,//预售商品开关 1开启 0关闭
                'sort'  =>  $goods_info['sort'] ?? 0,//排序
                'recommend' =>  !empty($goods_info['recommend']) ? json_decode($goods_info['recommend'], 1) : [],//商品推荐 is_best:精品 is_new:新品 is_hot:热卖 is_good:优品 is_benefit:促销
                'video_open'    =>  $goods_info['video_open'] ?? 0,//是否开启视频 1开启 0关闭
                'ficti' =>  $goods_info['ficti'] ?? 0,//虚拟销量
                'give_integral' =>  $goods_info['give_integral'] ?? 0,//赠送积分
                'is_sub'    =>  $goods_info['is_sub'] ?? 0,//是否单独分佣 1是 0否
            ];
            if(!empty($goods_info['is_limit']) && ($goods_info['is_limit'] == 1)){
                $assem_goods['limit_type'] = $goods_info['limit_type'] ?? 0;// 限购类型 1单次限购 2永久限购
                $assem_goods['limit_num'] = $goods_info['limit_num'] ?? 0;// 限购数量
            }
            if(!empty($goods_info['presale']) && ($goods_info['presale'] == 1)){
                $assem_goods['presale_time'] = explode(' - ', $goods_info['presale_time']);//预售时间段 [ "2022-07-20 00:00", "2022-08-20 00:00" ]
                $assem_goods['presale_day'] = $goods_info['presale_day'] ?? 0;//预售发货日 预售结束后几天内发货单位为天
            }
            if(!empty($goods_info['video_open']) && ($goods_info['video_open'] == 1)){
                $assem_goods['video_link'] = $goods_info['video_link'] ?? '';//视频链接地址
            }
            if(empty($sku_data[$goods_id])){
                $err_data[] = 'SPU:'.$goods_info['spu_code'].'SKU无数据';
                continue;
            }
            $assem_goods['attrs'] = $sku_data[$goods_id];
            $assem_goods['items'] = !empty($goods_attr_data[$goods_id]) ? array_values($goods_attr_data[$goods_id]) : [];
            if(!empty($goods_info['product_id'])){
                $assem_goods['act_product_id'] = $goods_info['product_id'];
                $success_data[$shop_id]['update'][] = $assem_goods;
            }else{
                $success_data[$shop_id]['add'][] = $assem_goods;
            }
        }
        return ['success' => $success_data, 'error' => $err_data];
    }

    /**
     * 推送商品到自有平台
     * @param object $platform_service
     * @param array $push_data
     * @param array $shop_info
     * @Description
     * @author wangqinghui
     * @date 2025-01-16 11:16
     * @return array
     */
    public function actPushGoods(object $platform_service, array $push_data, array $shop_info): array
    {
        $ret_data = ['code' => 0, 'msg' => ''];
        if(empty($platform_service)){
            $ret_data['msg'] = '平台服务不存在';
            return $ret_data;
        }
        if(empty($push_data)){
            $ret_data['msg'] = '推送数据为空';
            return $ret_data;
        }

        $err_msg = $add_err_msg = $update_goods_data = [];
        // 添加商品
        if(!empty($push_data['add'])){
            foreach ($push_data['add'] as $key => $value) {
                $old_goods_id = $value['act_gid'];
                unset($value['act_gid']);
                $res = $platform_service->getToken()->addProduct($value);
                if(empty($res['code']) || ($res['code'] != 1)){
                    $error_msg = $platform_service->getError();
                    $err_msg[] = '添加商品失败：'.$error_msg;
                    $add_err_msg[] = [
                        'type'  =>  0,
                        'goods_id'  =>  $old_goods_id,
                        'message' => $error_msg
                    ];
                    $update_goods_data[] = [
                        'id' => $old_goods_id,
                        'push_status'   => 3,
                    ];
                }else{
                    $update_goods_data[] = [
                        'id' => $old_goods_id,
                        'product_id'    =>  $res['data'],
                        'push_status'   =>  2,
                    ];
                }
            }
        }
        // 更新商品
        if(!empty($push_data['update'])){
            foreach ($push_data['update'] as $key => $value) {
                $old_goods_id = $value['act_gid'];
                $product_id = $value['act_product_id'];
                unset($value['act_gid'], $value['act_product_id']);
                $res = $platform_service->getToken()->updateProduct($product_id, $value);
                if(empty($res['code']) || ($res['code'] != 1)){
                    $error_msg = $platform_service->getError();
                    $err_msg[] = '更新商品失败：'.$error_msg;
                    $add_err_msg[] = [
                        'type'  =>  0,
                        'goods_id'  =>  $old_goods_id,
                        'message' => $error_msg
                    ];
                    $update_goods_data[] = [
                        'id' => $old_goods_id,
                        'push_status'   =>  3,
                    ];
                }else{
                    $update_goods_data[] = [
                        'id' => $old_goods_id,
                        'push_status'   =>  2,
                    ];
                }
            }
        }
        // 插入错误日志
        if(!empty($add_err_msg)){
            SelfGoodsPushMsgModel::mk()->insertAll($add_err_msg);
        }
        // 更新推送状态
        if(!empty($update_goods_data)){
            SelfGoodsModel::mk()->saveAll($update_goods_data);
        }
        if(!empty($err_msg)){
            $ret_data['msg'] = '错误信息：'.implode('<br>', $err_msg);
            return $ret_data;
        }
        $ret_data = ['code' => 1, 'msg' => '推送成功'];
        return $ret_data;
    }

    /**
     * 获取需要推送的商品sku库存
     * @param array $goods_ids
     * @Description
     * @author wangqinghui
     * @date 2025-01-17 10:06
     * @return array
     */
    public function getStockSkuList(array $goods_ids): array
    {
        $ret = ['error' => [], 'success' => []];
        if(empty($goods_ids)){
            $ret['error'] = ['同步失败:没有需要同步的商品'];
            return $ret;
        }
        // 获取商品信息
        $goods_data = SelfGoodsModel::mk()->where('id', 'in', $goods_ids)->column('id,spu_code,product_id,shop_id', 'id');
        if(empty($goods_data)){
            $ret['error'] = ['同步失败:需要同步的商品信息有误'];
            return $ret;
        }
        $err_data = [];
        foreach($goods_data as $id => $goods_info){
            if(empty($goods_info['product_id'])){
                $err_data[] = '商品SPU:'.$goods_info['spu_code'].'未同步到自有平台,请先推送到平台';
                continue;
            }
        }
        if(!empty($err_data)){
            $ret['error'] = $err_data;
            return $ret;
        }
        // 获取商品sku信息
        $field = 'id,goods_id,goods_nu,stock';
        $map = [
            ['goods_id', 'in', $goods_ids]
        ];
        $sku_data = SelfGoodsSkuModel::mk()->field($field)->where($map)->select()->toArray();
        $err_data = $success_stock = $stock_id_arr = [];
        foreach ($sku_data as $key => $value) {
            if(empty($value['stock']) || ($value['stock'] <= 0)){
                $err_data[] = 'SKU:'.$value['goods_nu'].'库存信息有误';
                continue;
            }
            $shop_id = $goods_data[$value['goods_id']]['shop_id'] ?? 0;
            if(empty($shop_id) || ($shop_id <= 0)){
                $err_data[] = 'SKU:'.$value['goods_nu'].'店铺信息有误';
                continue;
            }
            $success_stock[$shop_id][] = [
                'bar_code'      =>  $value['goods_nu'],
                'qty'      =>  $value['stock'],
            ];
            $stock_id_arr[$value['goods_nu']] = $value['id'];
        }
        if(!empty($err_data)){
            $ret['error'] = $err_data;
            return $ret;
        }
        return ['error' => [], 'success' => ['stock' => $success_stock, 'stock_id' => $stock_id_arr]];
    }

    /**
     * 推送商品库存
     * @param object $platform_service
     * @param array $stock_data
     * @param array $stock_ids
     * @Description
     * @author wangqinghui
     * @date 2025-01-17 10:12
     * @return array
     */
    public function actPushGoodsStock(object $platform_service, array $stock_data, array $stock_ids) : array
    {
        $ret_data = ['error' => [], 'success' => []];
        if(empty($platform_service)){
            $ret_data['error'] = ['平台服务不存在'];
            return $ret_data;
        }
        if(empty($stock_data) || empty($stock_ids)){
            $ret_data['error'] = ['推送库存数据为空'];
            return $ret_data;
        }
        $err_msg = [];
        foreach (array_chunk($stock_data, 50) as $chunk) {
            $push_ret = $platform_service->getToken()->updateProductStock($chunk);
            if(empty($push_ret['code']) || ($push_ret['code'] != 1)){
                $goods_nu_arr = array_column($chunk, 'bar_code');
                $err_msg[] = implode('|', $goods_nu_arr).'同步库存失败:'.$platform_service->getError();
            }else{
                $success_ids = array_values(array_intersect_key($stock_ids, array_column($chunk, 'bar_code', 'bar_code')));
                if(!empty($success_ids)){
                    $map = [
                        ['id', 'in', $success_ids]
                    ];
                    SelfGoodsSkuModel::mk()->where($map)->update(['sync_stock_status' => 1]);
                }
            }
        }
        if(!empty($err_msg)){
            $ret_data['error'] = $err_msg;
            return $ret_data;
        }
        return $ret_data;
    }
}